#include "Base/ThreadTool.h"

#if defined(USE_THREADS_POSIX)

struct self_actual_call {
  unsigned int (*func)(void *);
  void *arg;
};

static void *self_thread_create_thunk(void *arg)
{
  struct self_actual_call* ac = (struct self_actual_call*)arg;
  unsigned int (*func)(void *) = ac->func;
  void *real_arg = ac->arg;

  free(ac);

  (*func)(real_arg);

  return 0;
}

self_thread_t self_thread_create(unsigned int (*func) (void*), void *arg)
{
  self_thread_t t;
  struct self_actual_call* ac = (struct self_actual_call*)malloc(sizeof(struct self_actual_call));
  if(!ac)
    return self_thread_t_null;

  ac->func = func;
  ac->arg = arg;

  if(pthread_create(&t, NULL, self_thread_create_thunk, ac) != 0) {
    free(ac);
    return self_thread_t_null;
  }

  return t;
}

void self_thread_destroy(self_thread_t hnd)
{
  if(hnd != self_thread_t_null)
    pthread_detach(hnd);
}

int self_thread_join(self_thread_t *hnd)
{
  int ret = (pthread_join(*hnd, NULL) == 0);

  *hnd = self_thread_t_null;

  return ret;
}

#elif defined(USE_THREADS_WIN)

self_thread_t self_thread_create(unsigned int (SELF_STDCALL *func) (void*),
                                 void *arg)
{
#ifdef _WIN32_WCE
  return CreateThread(NULL, 0, func, arg, 0, NULL);
#else
  self_thread_t t;
  t = (self_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL);
  if((t == 0) || (t == (self_thread_t)-1L))
    return self_thread_t_null;
  return t;
#endif
}

void self_thread_destroy(self_thread_t hnd)
{
  CloseHandle(hnd);
}

int self_thread_join(self_thread_t *hnd)
{
  int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);

  self_thread_destroy(*hnd);

  *hnd = self_thread_t_null;

  return ret;
}

#endif /* USE_THREADS_* */

ThreadTool::ThreadTool(void)
{
}

ThreadTool::~ThreadTool(void)
{

}
